[bits 32]
%define ERROR_CODE nop  ; 若在相关的异常中cpu已经自动压入了错误码,为保持栈中格式统一,这里不做操作.
%define ZERO push 0     ; 若在相关的异常中cpu没有压入错误码,为了统一栈中格式,就手工压入一个0

extern idt_table
extern int_handler      ;声明外部函数
extern general_intr_handler
extern no_intr_handler

section .data
global intr_entry_table
intr_entry_table:

%macro VECTOR 2
section .text
intr%1entry:            ; 每个中断处理程序都要压入中断向量号,所以一个中断类型一个中断处理程序，自己知道自己的中断向量号是多少
   %2
   push ds
   push es
   push fs
   push gs
   pushad               ;eax,ecx,edx,ebx,esp,ebp,esi,edi
                        ; 如果是从片上进入的中断,除了往从片上发送EOI外,还要往主片上发送EOI
   mov al,0x20          ; 中断结束命令EOI
   out 0xa0,al          ; 向从片发送
   out 0x20,al          ; 向主片发送

   push %1              ;压入中断向量号
   call [idt_table + %1*4]
   jmp intr_exit

section .data
   dd    intr%1entry    ; 存储各个中断入口程序的地址，形成intr_entry_table数组
%endmacro

section .text
intr_exit:
    add esp,4   ;跳过中断号
    popad
    pop gs
    pop fs
    pop es
    pop ds
    add esp,4   ;跳过error code
    iret

intrOtherentry:
    push ds
    push es
    push fs
    push gs
    pushad               ;eax,ecx,edx,ebx,esp,ebp,esi,edi
                        ; 如果是从片上进入的中断,除了往从片上发送EOI外,还要往主片上发送EOI
    mov al,0x20          ; 中断结束命令EOI
    out 0xa0,al          ; 向从片发送
    out 0x20,al          ; 向主片发送

    call no_intr_handler

    popad
    pop gs
    pop fs
    pop es
    pop ds

    iret


VECTOR 0x00,ZERO
VECTOR 0x01,ZERO
VECTOR 0x02,ZERO
VECTOR 0x03,ZERO
VECTOR 0x04,ZERO
VECTOR 0x05,ZERO
VECTOR 0x06,ZERO
VECTOR 0x07,ZERO
VECTOR 0x08,ERROR_CODE
VECTOR 0x09,ZERO
VECTOR 0x0a,ERROR_CODE
VECTOR 0x0b,ERROR_CODE
VECTOR 0x0c,ZERO
VECTOR 0x0d,ERROR_CODE
VECTOR 0x0e,ERROR_CODE
VECTOR 0x0f,ZERO
VECTOR 0x10,ZERO
VECTOR 0x11,ERROR_CODE
VECTOR 0x12,ZERO
VECTOR 0x13,ZERO
VECTOR 0x14,ZERO
VECTOR 0x15,ZERO
VECTOR 0x16,ZERO
VECTOR 0x17,ZERO
VECTOR 0x18,ERROR_CODE
VECTOR 0x19,ZERO
VECTOR 0x1a,ERROR_CODE
VECTOR 0x1b,ERROR_CODE
VECTOR 0x1c,ZERO
VECTOR 0x1d,ERROR_CODE
VECTOR 0x1e,ERROR_CODE
VECTOR 0x1f,ZERO
VECTOR 0x20,ZERO

section .data
   times 230 dd intrOtherentry